package muhnes.sizoo.dal;

import java.util.List;
import muhnes.sizoo.HibernateUtilZoologia;
import muhnes.sizoo.modelo.Animal;
import muhnes.sizoo.modelo.Especimen;
import muhnes.sizoo.modelo.Internacional;
import muhnes.sizoo.modelo.Municipio;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

/**
 * Clase que implementa los metodos definidos en EspecimenDao
 * @author Ricardo Orellana
 */
public class EspecimenDaoImpl extends GenericoDAO< Especimen, String > 
                              implements EspecimenDao{
    
    public EspecimenDaoImpl() {
        super( HibernateUtilZoologia.getSessionFactory() );
    }
    
    @Override
    protected Class<?> getClaseEntidad () {
        return Especimen.class;
    }

    /**
     * Método que devuelve una lista de especimenes segun el animal al que pertenecen
     * 
     */
    @Override
    public List<Especimen> buscarPorAnimal (Animal animal){  
        Session sesion = fabricaSesion.getCurrentSession();
        String hql = "from Especimen where codigoanimal = :codigo";
        Query consulta = sesion.createQuery(hql);
        consulta.setParameter( "codigo", animal.getCodigoanimal());
        List< Especimen > especimenes = consulta.list();
        return especimenes;
    }
    
    /**
     * Método que devuelve una lista de municipios donde fueron recolectados los especimenes
     *  
     */
    @Override
    public Municipio buscarMunicipiosAsociados(Especimen especimen){ 
        Session sesion = fabricaSesion.getCurrentSession();
        String hql = "select m.* "
                + "from zoologia.especimen as e, "
                + "zoologia.recoleccion as r, "
                + "zoologia.nacional as n, "
                + "zoologia.zona as z, "
                + "zoologia.municipio as m "
                + "where e.codigoespecimen = :codigo "
                + "and e.codigorecoleccion = r.codigorecoleccion "
                + "and r.codigorecoleccion = n.codigorecoleccion "
                + "and n.codigozona = z.codigozona "
                + "and z.codigomunicipio = m.codigomunicipio;";
        SQLQuery consulta = sesion.createSQLQuery(hql);
        consulta.setParameter( "codigo", especimen.getCodigoespecimen());
        Municipio municipio = (Municipio)consulta.addEntity(Municipio.class).uniqueResult();
        return municipio;
    }
    
    /**
     * Método que devuelve una lista de especimenes que fueron recolectados
     * fuera del país 
     */
    @Override
    public Internacional buscarRecoleccionInternacional (Especimen especimen){ 
        Session sesion = fabricaSesion.getCurrentSession();
        String hql = "select i.* from "
                + "zoologia.especimen as e, "
                + "zoologia.recoleccion as r, "
                + "zoologia.internacional as i "
                + "where e.codigoespecimen = :codigo "
                + "and e.codigorecoleccion = r.codigorecoleccion "
                + "and r.codigorecoleccion = i.codigorecoleccion;";
        SQLQuery consulta = sesion.createSQLQuery(hql);
        consulta.setParameter( "codigo", especimen.getCodigoespecimen());
        Internacional internacional = (Internacional)consulta.addEntity(Internacional.class).uniqueResult();
        return internacional;
    }

    /**
     * Método que devuelve una lista de fotos de los animales
     * 
     */
    @Override
    public List<String> buscarFotosPorAnimal(Animal animal){ 
        Session sesion = fabricaSesion.getCurrentSession();
        String hql = "select distinct especimen.fotografia from zoologia.Animal animal, zoologia.Especimen especimen, zoologia.Recoleccion recoleccion, zoologia.Nacional nacional,  zoologia.Zona zona, zoologia.Municipio municipio where especimen.codigoanimal = :codigo"
                  + " and especimen.codigorecoleccion = recoleccion.codigorecoleccion and recoleccion.codigorecoleccion = nacional.codigorecoleccion and nacional.codigozona = zona.codigozona and zona.codigomunicipio = municipio.codigomunicipio";
        SQLQuery consulta = sesion.createSQLQuery(hql);
        consulta.setParameter( "codigo", animal.getCodigoanimal());
        List< String > especimenes = consulta.list();
        return especimenes;
    }

    /**
     * Método que devuelve una lista de especimenes que se encuentran en revision 
     */
    @Override
    public List<Especimen> buscarEspecimenesEnRevision() {
        Session sesion = fabricaSesion.getCurrentSession();
        String hql = "from Especimen where upper(estado) = 'REVISION'";
        Query consulta = sesion.createQuery( hql );
        List< Especimen > especimenes = consulta.list();
        return especimenes;
    }
    
    /**
     * Método que verifica que el especimen sea unico 
     *
     */
    @Override
    public boolean verificarUnicidad(Especimen entidad) {
        Session sesion = fabricaSesion.getCurrentSession();        
        String hql = "from Especimen where upper(codigoespecimen) = :codigoespecimen";
        Query consulta = sesion.createQuery( hql );
        consulta.setParameter("codigoespecimen", entidad.getCodigoespecimen().toUpperCase());
        return consulta.uniqueResult() != null ? true : false;
    }
    
    /**
     * Método que verifica que la entidad sea independiente de las demas entidades
     *  
     */
    @Override
    public boolean verificarDependencia (Especimen entidad) {
        Session sesion = fabricaSesion.getCurrentSession();        
        String hql = "from Restauracion where especimen.codigoespecimen = :codigo";
        Query consulta = sesion.createQuery( hql );
        consulta.setParameter("codigo",entidad.getCodigoespecimen());
        return !consulta.list().isEmpty();
    }
    
    /**
     * Método que devuelve una lista de habitats de los especimenes.
     *  
     */
    @Override
    public List<String> buscarHabitats() {
        Session sesion = fabricaSesion.getCurrentSession();        
        String sql = "select distinct e.habitat from zoologia.especimen e";
        SQLQuery consulta = sesion.createSQLQuery( sql );
        return consulta.list();
    }
    
}
